<?php

/*
 * Camelot PHP Tools
 *
 * @version 2.0
 * @author Bendsoft
 * @package PHP Tools
 * @subpackage Camelot
 * @license FreeBSD License (www.bendsoft.com/licensing/)
 *
 */

/**
 * Class with functions to handle and decode data from
 * Camelot .NET Connector
 *
 * @author Bendsoft
 */
class DecodeDump extends CamelotDump {

    /**
     * Function to fetch a packet
     *
     * @access	public
     * @param int $id This is the camelot_dump_id
     * @return	string The packet in raw format (still encoded)
     */
    function get_packet($id) {

        if (!is_numeric($id))
            return 'msg:201';

        parent::open($id);
        $packet = parent::getCamelotDumpPacket();

        return $packet;
    }

    /**
     * Function to decode packets
     *
     * @access	public
     * @param string $packet
     * @return	string|object The string is an error message
     */
    function decode_packet($packet) {

        if (!$packet)
            return 'msg:200';

        // Todo - Add base64 check

        $packet = base64_decode($packet);
        $packet = gzinflate($packet);
        $packet = simplexml_load_string($packet);

        return $packet;
    }

}

/**
 * Class with functions to handle and insert lists (and it's schema) from
 * Camelot .NET Connector
 *
 * @author Bendsoft
 */
class InsertList extends CamelotList {

    /**
     * Function to insert lists and it's contents
     *
     * @access	public
     * @param int $id This is the id of the dump - camelot_dump.camelot_dump_id
     * @return	int The id of the created list
     */
    function insert_list($id) {

        # Failcheck
        if (!is_numeric($id))
            return 'msg:202';

        # Open required objects
        $decode_obj = new DecodeDump();
        $content_obj = new InsertContent();

        # Retreive packet
        $packet = $decode_obj->get_packet($id);

        # Parsing the package to something useful
        $packet = $decode_obj->decode_packet($packet);

        # Convert the schema to xml
        $schema = $packet->Schema;
        $schema_xml = $schema->asXML(); # Konvertera till xml
        # Check if there is an active list WITH the same ID (MOSS GUID) and THAT is newer
        if ($this->check_active($packet->ID, $packet->Modified) == 0) {
            
            
            # Inserts new list
            parent::setCamelotListIdExternal($packet->ID);
            parent::setCamelotListTitle($packet->Title);
            parent::setCamelotListDescription($packet->Description);
            parent::setCamelotListSchema($schema_xml);
            parent::setCamelotListDateModified($this->format_rfc3339_date($packet->Modified));
            parent::setCamelotListDateLastdeleted($this->format_rfc3339_date($packet->LastDeleted));
            parent::setCamelotListDateCreated($this->format_rfc3339_date($packet->Created));
            parent::setCamelotListItemcount($packet->ItemCount);
            parent::setCamelotListStatus('1');
            $new_id = parent::save('');

            # Set previous list WITH the same ID as inactive (if there is one)
            if ($new_id != 0)
                $this->reset_active($packet->ID, $new_id);

            # Insert list content
            $content_obj->insert_content($id, $new_id);
            
        } else {
            $new_id = 0;
        }

        # Closing objects
        $decode_obj = null;
        $content_obj = null;

        # returnering
        return $new_id;
    }
    
    private function format_rfc3339_date($date) {
        $date = str_replace("T", " ", $date);
        $date = str_replace("Z", "", $date);
        return $date;
    }
    
    

    /**
     * Function modify active lists
     *
     * @access	private
     * @param string $id_external The external id (MOSS GUID)
     * @param string $new_id If not set ALL posts responding to the external id will be set as inactive
     * @return	void
     */
    private function reset_active($id_external, $new_id='') {

        if ($new_id) {
            parent::update("camelot_list_status='0' WHERE camelot_list_id_external='$id_external' AND camelot_list_id != $new_id");
        } else {
            parent::update("camelot_list_status='0' WHERE camelot_list_id_external='$id_external'");
        }
    }

    /**
     * Function to check active list
     *
     * @access	private
     * @param string $id_external The external id (MOSS GUID)
     * @param string $date_modified Date when the post where last modified
     * @return	int If 0 then there where no post, otherwise the int is the id of the post
     */
    private function check_active($id_external, $date_modified) {
        return parent::open("WHERE camelot_list_id_external ='$id_external' AND camelot_list_status='1' AND camelot_list_date_modified >= '$date_modified'");
    }

}

/**
 * Class with functions to handle and insert data (the actual list data) from
 * Camelot .NET Connector
 *
 * @author Bendsoft
 */
class InsertContent extends CamelotContent {

    /**
     * Function to insert the content posts of a list
     *
     * @access	public
     * @param int $id
     * @param int $list_id This is the id generated and returned by InsertList.insert_list
     * @return	string Comma separated string with the id's of the content
     */
    function insert_content($id,$list_id) {

        # Failcheck
        if (!is_numeric($id))
            return 'msg:203';
        if (!is_numeric($list_id))
            return 'msg:204';

        # Open required objects
        $decode_obj = new DecodeDump();

        # Retreive packet
        $packet = $decode_obj->get_packet($id);

        # Parsing the package to something useful
        $packet = $decode_obj->decode_packet($packet);

        # Get Row from $dump->Content
        $content = $packet->Content->Row;

        # Store content
        $ret = "";
        foreach ($content as $key) {
            parent::setCamelotContentCamelotListIdExternal($packet->ID);
            parent::setCamelotContentCamelotListId($list_id); #parent id
            parent::setCamelotContentRowIndex($key->attributes()->Index);
            parent::setCamelotContentContent($key->asXML());
            $ret .= parent::save('');
            $ret .= ",";
        }

        # Closing objects
        $decode_obj = null;

        return $ret;
    }


    /**
     * Region setter for camelot_content_camelot_list_id, it's a pointer to the parent id in camelot_list
     *
     * @access	public
     * @param int $camelot_content_camelot_list_id
     * @return	void
     */
    public function setCamelotContentCamelotListId($camelot_content_camelot_list_id) {
        $this->camelot_content_camelot_list_id = $camelot_content_camelot_list_id;
    }

    /**
     * Region getter for camelot_content_camelot_list_id, requires object to be set
     *
     * @access	public
     * @return	int
     */
    public function getCamelotContentCamelotListId() {
        return $this->camelot_content_camelot_list_id;
    }

}



?>
